﻿package core;


// ====================================================== Математические расчеты
public final class Mat {

//========================================================================= Биты
public static final int BIT0 = 0x01;
public static final int BIT1 = 0x02;
public static final int BIT2 = 0x04;
public static final int BIT3 = 0x08;
public static final int BIT4 = 0x10;
public static final int BIT5 = 0x20;
public static final int BIT6 = 0x40;
public static final int BIT7 = 0x80;

//======================================================== Глобальные переменные
// CRC
private static int crc = 0; // Результат вычисления CRC
private static int[] crcTable = null; // Таблица для быстрого вычисления CRC


// =================================================== Перевести в 16-ричный вид
public static String bytesToHex(byte[] from, String determ) {

	StringBuffer result = new StringBuffer(64);

	if (determ == null) {
		determ = "";
	}

	for (int q = 0; q < from.length; ++q) {
		int byt = from[q];
		if (byt < 0) {
			byt += 256;
		}
		if (byt <= 15) {
			result.append("0");
		}
		result.append(Integer.toHexString((byt))).append(determ);
	}

	return result.toString();
}


//========================================================= Создание CRC-таблицы
public static int[] crcTableMake() {

	crcTable = new int[256];
	for (int n = 0; n < 256; n++) {
		int c = n;
		for (int k = 8; --k >= 0;) {
			if ((c & 1) != 0) {
				c = 0xedb88320 ^ (c >>> 1);
			} else {
				c = c >>> 1;
			}
		}
		crcTable[n] = c;
	}
	return crcTable;
}


// ============================================================== Удалить смайлы
public static String delSmile(String inText, int maxSmiles, char smlRemChar) {

	if (inText != null && inText.length() > 0) {

		StringBuffer tmp;

		tmp = new StringBuffer(inText);

		//		if (tmp.charAt(tmp.length()) == Setting.SMILE_CHAR) {
		//			tmp.append('.');
		//		}

		int smlCount = 0;

		for (int q = 0; q < tmp.length(); ++q) {
			if (tmp.charAt(q) == Setting.SMILE_CHAR) {
				if (++smlCount > maxSmiles) {
					tmp.delete(q, q + 2);
					if (smlRemChar != Setting.NO_REPLACE_CHAR) {
						tmp.insert(q, smlRemChar);
					}
					--q;
				} else { // Найден смайл, но количество является еще допустимым
					++q;
				}
			}
		}

		if (tmp.length() > 0) {
			if (tmp.charAt(tmp.length() - 1) == Setting.SMILE_CHAR) {
				tmp.append('.');
			}
		}

		return tmp.toString();

	} else {
		return "";
	}
}


//=============================================================== Возвращает CRC
public static int getCrc() {

	return crc;
}


// ====================================================== Вычислить длину целого
public static int getIntLen(int intValue) {

	int len = 0;

	do {
		len++;
		intValue >>>= 7;
	} while (intValue > 0);

	return len;
}


//==================================================================== Сброс CRC
public static void crcReset() {

	crc = 0;
}


//=================================================================== Расчет CRC
// Для байтового значения
public static void crcUpdate(int bval) {

	int c = ~crc;
	c = crcTable[(c ^ bval) & 0xff] ^ (c >>> 8);
	crc = ~c;
}


// Ддя байтового массива частично
public static void crcUpdate(byte[] buf, int off, int len) {

	int c = ~crc;
	while (--len >= 0) {
		c = crcTable[(c ^ buf[off++]) & 0xff] ^ (c >>> 8);
	}
	crc = ~c;
}


// Ддя байтового массива целиком
public static void crcUpdate(byte[] buf) {

	crcUpdate(buf, 0, buf.length);
}


// ============================================================== Байты в строку
public static String iso2utf(byte[] in, int offset, int len) {

	StringBuffer out = new StringBuffer(len); // Возвращаемая строка
	int q;
	int w;

	len += offset;

	for (q = offset; q < len; q++) {
		w = in[q];
		if (w < 0) {
			w += 1120; // Преобразуем из ISO 8859-5 в UTF-8
		}
		out.append((char) w);
	}
	return out.toString();
}


public static String iso2utf(byte[] in, int len) {

	return iso2utf(in, 0, len);
}


public static String iso2utf(byte[] in) {

	return iso2utf(in, 0, in.length);
}


// ============================================================== Строка в байты
public static void utf2iso(String text, byte[] bytes, int offset) {

	int q; // Счетчик цикла
	int length = text.length(); // Длина преобращуемого сообщения
	int chr; // Временный символ

	if ((length + offset) > bytes.length) {
		Mess.err("Mat.utf2iso", "Сообщение не умещается в предоставленный массив");
		text = text.substring(0, bytes.length - offset);
		length = text.length();
	}

	for (q = offset; q < length; q++) {
		chr = text.charAt(q);
		if ((chr >= 0x401) && (chr <= 0x45f)) {
			chr -= 1120; // 1120=0x460; преобразуем в ISO 8859-5
		}
		bytes[q] = (byte) chr;
	}

}


public static byte[] utf2iso(String text, int offset) {

	byte[] ret = new byte[Math.min(Setting.MAX_TEXT_LEN, text.length() + offset)];
	utf2iso(text, ret, offset);
	return (ret);
}


public static byte[] utf2iso(String text) {

	return utf2iso(text, 0);
}


// ===================================================== Перевести в байт-массив
public static byte[] hexToBytes(String text) {

	int len = text.length() >> 1;

	byte[] bytes = new byte[len];

	for (int q = 0; q < len; ++q) {
		String sub = text.substring(q << 1, (q << 1) + 2);
		int byt = Integer.parseInt(sub, 16);
		if (byt > 127) {
			byt -= 256;
		}
		bytes[q] = (byte) byt;
	}

	return bytes;
}


// ===================================================== Извлечь целое из строки
public static int getInt(String text) {

	int res = Integer.MIN_VALUE;

	try {

		int start = -1;
		int end = text.length();

		int q;
		int chr;
		for (q = 0; q < text.length(); ++q) {
			chr = text.charAt(q);
			if ((chr >= 43) && (chr <= 57)) {
				if ((chr == 43) || (chr == 45) || (chr >= 48)) {
					start = q;
					break;
				}
			}
		}

		if (start >= 0) {
			for (q = start + 1; q < text.length(); ++q) {
				chr = text.charAt(q);
				if ((chr >= 48) && (chr <= 57)) {
				} else {
					end = q;
					break;
				}
			}
		}

		if ((start > 0) && ((end - start) > 0)) {
			String intText = text.substring(start, end);
			try {
				res = Integer.parseInt(intText);
			} catch (Exception e) {
				Mess.err("", "Ошибка извлечения целого. start=" + start + ", end="
						+ end + " Текст=" + text);
			}
		}
	} catch (Exception e) {
		Mess.err("Mat.getInt", e);
	}

	return res;
}


// ======================================================================== Тест
/*
 * public static void main(String[] args) {
 * 
 * Mess.m("Main.init", "TEST STARTED. Ver: " + Setting.version);
 * 
 * Mess.m("Mat.main", delSmile("#####", 2, '.')); Mess.m("Mat.main",
 * delSmile("#####", 0, '.')); Mess.m("Mat.main", delSmile("#####", 0,
 * Setting.NO_REPLACE_CHAR)); Mess.m("Mat.main", delSmile("#1V#2a#3l#4entine",
 * 0, Setting.NO_REPLACE_CHAR)); Mess.m("Mat.main",
 * delSmile("#1V#2a#3l#4entine", 0, '.')); Mess.m("Mat.main",
 * delSmile("#1V#2a#3l#4entine", 2, '.')); Mess.m("Mat.main",
 * delSmile("#1V#2a#3l#4entine", 4, '.')); Mess.m("Mat.main",
 * delSmile("#1V#2a#3l#4entine", 5, '.')); Mess.m("Mat.main",
 * delSmile("#1V#2a#3l#4entine", 4, Setting.NO_REPLACE_CHAR));
 * Mess.m("Mat.main", delSmile("#1V#2a#3l#4entine", 5,
 * Setting.NO_REPLACE_CHAR)); Mess .m( "Mat.main", delSmile(
 * "#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О# О#О#О#О#О#О#О#О#О#Ч#Ч#Ч#Ч#Ч#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О# О#О#О#О#О#О#О#О#О#Ч#Ч#Ч#Ч#Ч#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О#О# О#О#О#О#О#О#О#О#О#Ч#Ч#Ч#Ч#Ч"
 * , 4, Setting.NO_REPLACE_CHAR));
 * 
 * Mess.m("Main.init", "TEST END."); }
 */


}
